#include "Socket.h"
#include "Log.h"
int g_nCounter = 0;
///////////////////////////////////////////////////////
CSocket::CSocket()
{
}

CSocket::~CSocket()
{
	close(m_sockfd);
}


bool CSocket::setNonBlock(int sockfd)
{
	int opts = fcntl(sockfd , F_GETFL);
	if(-1 == opts)
	{
		debug_output("%s\n" , "fcntl F_GETFL is faild");
		return false;
	}

	opts = opts | O_NONBLOCK;
	if(fcntl(sockfd , F_SETFL , opts) < 0)
	{
		debug_output("%s\n" , "fcntl F_SETFL is faild");
		return false;
	}
	return true;
}

bool CSocket::Bind(unsigned int nPort)
{
	m_sockfd = socket(PF_INET , SOCK_STREAM , 0);
	if(-1 == m_sockfd)
	{
		debug_output("%s\n" , "Create Socket is faild");
		return false;
	}

	/// 允许地址重用
	int reuse = 1;
	setsockopt(m_sockfd , SOL_SOCKET , SO_REUSEADDR , &reuse , sizeof(reuse));
	int nRecvBuf = sizeof(PacketHeader);
	setsockopt(m_sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
/*	bool bRet = setNonBlock(m_sockfd);
	if(bRet == false)
	{
		return false;
	}*/

	struct sockaddr_in servaddr;
	bzero(&servaddr , sizeof(servaddr));

	servaddr.sin_family = PF_INET;
	servaddr.sin_port = htons(nPort);
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	int nRet = bind(m_sockfd , (struct sockaddr*)&servaddr , sizeof(servaddr));
	if(-1 == nRet)
	{
		debug_output("%s\n" , "bind is faild");
		return false;
	}

	nRet = listen(m_sockfd , 5);
	if(-1 == nRet)
	{
		debug_output("%s\n" , "listen is faild");
		return false;
	}

/*	struct epoll_event ev;
	bzero(&ev , sizeof(ev));
	ev.data.fd = m_sockfd;
	ev.events = EPOLLIN | EPOLLET;
	nRet = epoll_ctl(epfd , EPOLL_CTL_ADD , m_sockfd , &ev);
	if(-1 == nRet)
	{
		debug_output("%s\n" , "epoll_ctl is faild");
		return false;
	}*/

	return true;
}

bool CSocket::Listen(int &nSocket)
{
	struct sockaddr_in addr;
	int size = sizeof(addr);
	char szIp[16];
	int nfds , i;
	nSocket = accept(m_sockfd , (struct sockaddr*)&addr, (socklen_t*)&size);
	if(nSocket == -1)
	{
		if(errno == EINTR)
		{
	//		continue;
		}
		debug_output("Error accept is Faild error = %d\n", errno);
		return false;
	}
	bzero(&szIp, sizeof(szIp));
	strcpy(szIp, inet_ntoa(addr.sin_addr));
	g_nCounter++;			
	debug_output("Success New Client Connect Ip = %s, Port = %d, socket = %d, onLineClient = %d\n" , szIp, ntohs(addr.sin_port), nSocket, g_nCounter);
	return true;
}
